package com.ofps.forms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ofps.common.core.domain.entity.SysUser;
import com.ofps.common.utils.StringUtils;
import com.ofps.forms.common.utils.JwtUtil;
import com.ofps.forms.common.utils.R;
import com.ofps.forms.common.utils.TokenUtil;
import com.ofps.forms.mapper.*;
import com.ofps.forms.domain.*;
import com.ofps.forms.service.*;
import com.ofps.system.mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import com.ofps.forms.domain.Dto.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.ofps.common.utils.SecurityUtils.*;
import static com.ofps.common.utils.SecurityUtils.getUserId;


@Service
public class MyFormServiceImpl extends ServiceImpl<MyFormMapper, MyForm> implements MyFormService {

    //注入FormDao
    @Resource
    private MyFormMapper myFormMapper;
    @Resource
    private AnswerBlankMapper answerBlankMapper;
    @Resource
    private AnswerCheckboxMapper answerCheckboxMapper;
    @Resource
    private AnswerDatetimeMapper answerDatetimeMapper;
    @Resource
    private AnswerRadioMapper answerRadioMapper;
    @Resource
    private AnswerSlideMapper answerSlideMapper;
    @Resource
    private AnswerListboxMapper answerListboxMapper;
    @Resource
    private AnswerScoreMapper answerScoreMapper;
    //questionDao
    @Resource
    private QuestionBlankMapper questionBlankMapper;
    @Resource
    private QuestionRadioMapper questionRadioMapper;
    @Resource
    private QuestionCheckboxMapper questionCheckboxMapper;
    @Resource
    private QuestionListboxMapper questionListboxMapper;
    @Resource
    private QuestionSlideMapper questionSlideMapper;
    @Resource
    private QuestionDatetimeMapper questionDatetimeMapper;
    @Resource
    private OptionMapper optionMapper;
    @Resource
    private QuestionScoreMapper questionScoreMapper;

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private WriteRecordMapper writeRecordMapper;

    /**
     * 传入表单ID(注意传入时进行校验表单是否存在 防止空指针错误)
     * 返回该表单的所有问题 按设计表单时的序号排序后返回
     */
    private List<Object> getQuestions(String formId) {
        //type 0 blank  填空题封装到questions中
        List<Object> questions = new LinkedList<>(questionBlankMapper.selectList(
                new QueryWrapper<QuestionBlank>().eq("form_id", formId)
        ));

        //type 1 radio
        //所有单项选择题  封装option
        //循环插入到radioAnswerList
        questionRadioMapper.selectList(
                new QueryWrapper<QuestionRadio>().eq("form_id", formId)
        ).forEach(radio -> questions.add(new RadionAnswerDto()
                        .setId(radio.getId())
                        .setUserId(radio.getUserId())
                        .setFormId(radio.getFormId())
                        .setOrderId(radio.getOrderId())
                        .setMust(radio.getMust())
                        .setQuestionName(radio.getQuestionName())
                        .setQuestionType(radio.getQuestionType())
                        .setQuestionInfo(radio.getQuestionInfo())
                        .setOptions(
                                optionMapper.selectList(
                                        new QueryWrapper<Option>().eq("question_id", radio.getId()))
                        )
                )
        );

        //type 2 checkbox question
        questionCheckboxMapper.selectList(
                new QueryWrapper<QuestionCheckbox>().eq("form_id", formId)
        ).forEach(checkbox -> questions.add(new CheckboxOptionDto()
                .setId(checkbox.getId())
                .setUserId(checkbox.getUserId())
                .setFormId(checkbox.getFormId())
                .setOrderId(checkbox.getOrderId())
                .setMust(checkbox.getMust())
                .setQuestionName(checkbox.getQuestionName())
                .setQuestionType(checkbox.getQuestionType())
                .setQuestionInfo(checkbox.getQuestionInfo())
                .setOptionMin(checkbox.getOptionMin())
                .setOptionMax(checkbox.getOptionMax())
                .setOptions(
                        optionMapper.selectList(
                                new QueryWrapper<Option>().eq("question_id", checkbox.getId())
                        )
                ))
        );
        //type 3 listbox
        questionListboxMapper.selectList(
                new QueryWrapper<QuestionListbox>().eq("form_id", formId)
        ).forEach(listbox -> questions.add(
                new ListboxAnswerDto()
                        .setId(listbox.getId())
                        .setUserId(listbox.getUserId())
                        .setFormId(listbox.getFormId())
                        .setOrderId(listbox.getOrderId())
                        .setMust(listbox.getMust())
                        .setQuestionName(listbox.getQuestionName())
                        .setQuestionType(listbox.getQuestionType())
                        .setQuestionInfo(listbox.getQuestionInfo())
                        .setOptions(
                                optionMapper.selectList(
                                        new QueryWrapper<Option>().eq("question_id", listbox.getId())
                                )
                        )
        ));

        //type 4 slide
        questions.addAll(questionSlideMapper.selectList(
                new QueryWrapper<QuestionSlide>().eq("form_id", formId)
        ));
        //type 5 datetime 时间日期
        questions.addAll(questionDatetimeMapper.selectList(
                new QueryWrapper<QuestionDatetime>().eq("form_id", formId)
        ));
        //type 6 socre 评分题
        questions.addAll(questionScoreMapper.selectList(
                new QueryWrapper<QuestionScore>().eq("form_id", formId)
        ));

        //根据序号排序
        questions.sort(new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                return getQuestionOrderId(o1) - getQuestionOrderId(o2);
            }
        });

        return questions;

    }

    /**
     * 根据传入的问题数组查找对应问题填写过的答案
     * 需要判断是个人表单还是企业表单的答案(未提交的)
     * 查询的是暂时保存的答案
     * is_submit==false
     */
    private List<Object> getAnswersStore(String recordId, List<Object> questions, Boolean type) {
        List<Object> answers = new LinkedList<>();

        for (Object question : questions) {
            //根据问题类型去对应表格查询答案
            switch (getQuestionType(question)) {
                case 0: {
                    //填空题
                    AnswerBlank answerBlank = answerBlankMapper.selectOne(new QueryWrapper<AnswerBlank>()
                            .eq("record_id", recordId)
//                            .eq("user_id", userId)
                            .eq("question_id", ((QuestionBlank) question).getId())
//                            .eq("is_submit", false)
                            .isNull(!type, "flow_inst_id")
                            .isNotNull(type, "flow_inst_id"));
                    answers.add(answerBlank == null ? new HashMap<>() : answerBlank);
//                    answers.add(answerBlank == null ? new AnswerBlank() : answerBlank);
                }
                break;
                case 1: {
                    //单选
                    AnswerRadio answerRadio = answerRadioMapper.selectOne(new QueryWrapper<AnswerRadio>()
                            .eq("record_id", recordId)
//                            .eq("user_id", userId)
                            .eq("question_id", ((RadionAnswerDto) question).getId())
//                            .eq("is_submit", false)
                            .isNull(!type, "flow_inst_id")
                            .isNotNull(type, "flow_inst_id"));
                    answers.add(answerRadio == null ? new HashMap<>() : answerRadio);
                }
                break;
                case 2: {
                    //多选 CheckboxOptionDto
                    List<AnswerCheckbox> answerCheckboxEntities = answerCheckboxMapper.selectList(new QueryWrapper<AnswerCheckbox>()
                            .eq("record_id", recordId)
//                            .eq("user_id", userId)
                            .eq("question_id", ((CheckboxOptionDto) question).getId())
//                            .eq("is_submit", false)
                            .isNull(!type, "flow_inst_id")
                            .isNotNull(type, "flow_inst_id"));
                    //没有填写过答案
                    if (answerCheckboxEntities.size() == 0) {
                        answers.add(new HashMap<>());
                        break;
                    }
                    ArrayList<String> optionId = new ArrayList<>();
                    answerCheckboxEntities.forEach(option -> optionId.add(option.getOptionId()));

                    answers.add(new CheckboxAnswerDto()
                            .setId(answerCheckboxEntities.get(0).getId())
                            .setUserId(answerCheckboxEntities.get(0).getUserId())
                            .setFormId(answerCheckboxEntities.get(0).getFormId())
                            .setQuestionId(answerCheckboxEntities.get(0).getQuestionId())
                            .setOptionId(optionId)
                            .setCreateTime(answerCheckboxEntities.get(0).getCreateTime())
                            .setIsSubmit(answerCheckboxEntities.get(0).getIsSubmit())
                    );
                }
                break;
                case 3: {
                    //下拉列表
                    AnswerListbox answerListbox = answerListboxMapper.selectOne(new QueryWrapper<AnswerListbox>()
                            .eq("record_id", recordId)

//                            .eq("user_id", userId)
                            .eq("question_id", ((ListboxAnswerDto) question).getId())
//                            .eq("is_submit", false)
                            .isNull(!type, "flow_inst_id")
                            .isNotNull(type, "flow_inst_id"));
                    answers.add(answerListbox == null ? new HashMap<>() : answerListbox);

                }
                break;
                case 4: {
                    //滑块
                    AnswerSlide answerSlide = answerSlideMapper.selectOne(new QueryWrapper<AnswerSlide>()
                            .eq("record_id", recordId)
//                            .eq("user_id", userId)
                            .eq("question_id", ((QuestionSlide) question).getId())
                            .eq("is_submit", false).isNull(!type, "flow_inst_id")
                            .isNotNull(type, "flow_inst_id"));
                    answers.add(answerSlide == null ? new HashMap<>() : answerSlide);

                }
                break;
                case 5: {
                    //日期时间
                    AnswerDatetime answerDatetime = answerDatetimeMapper.selectOne(new QueryWrapper<AnswerDatetime>()
                            .eq("record_id", recordId)
//                            .eq("user_id", userId)
                            .eq("question_id", ((QuestionDatetime) question).getId())
//                            .eq("is_submit", false)
                            .isNull(!type, "flow_inst_id")
                            .isNotNull(type, "flow_inst_id"));

                    if (null == answerDatetime) {
                        answers.add(new HashMap<>());
                        break;
                    }
                    Date[] dates = {answerDatetime.getBeginTime(), answerDatetime.getEndTime()};
                    //日期时间
                    answers.add(new DateTimeAnswerDto().setId(answerDatetime.getId())
                            .setUserId(answerDatetime.getUserId())
                            .setFormId(answerDatetime.getFormId())
                            .setQuestionId(answerDatetime.getQuestionId())
                            .setCreateTime(answerDatetime.getCreateTime())
                            .setBeginAndEnd(dates));
                }
                break;
                case 6: {
                    //评分题
                    AnswerScore answerScore = answerScoreMapper.selectOne(new QueryWrapper<AnswerScore>()
                            .eq("record_id", recordId)
//                            .eq("user_id", userId)
                            .eq("question_id", ((QuestionScore) question).getId())
//                            .eq("is_submit", false)
                            .isNull(!type, "flow_inst_id")
                            .isNotNull(type, "flow_inst_id"));
                    answers.add(answerScore == null ? new HashMap<>() : answerScore);
                }
                break;
                default:
                    break;
            }

        }
        return answers;
    }

    /***
     *  检查当前用户是否存在未提交的表单
     *  false 存在未提交 true不存在 ->新表单
     * @param userId
     * @param formId
     * @param type
     * @return
     */

    private boolean checkIfSubmit(Long userId, String formId, Boolean type) {
        //优化
        WriteRecord writeRecord = writeRecordMapper.selectOne(
                new QueryWrapper<WriteRecord>()
                        .eq("form_id", formId)
                        .eq("user_id", userId)
                        .eq("is_submit", false)
        );
        if (writeRecord == null)
            return true;
        else
            return false;
        //check in every answerTable

        //第一次 该问卷对应id与userId都没有记录
        //之前填过 但是未提交
        //存在未提交的答案 就说明
//        return answerBlankMapper.selectList(new QueryWrapper<AnswerBlank>()
//                        .eq("user_id", userId)
//                        .eq("form_id", formId)
//                        .eq("is_submit", false)
//                        .isNull(!type, "flow_inst_id")
//                        .isNotNull(type, "flow_inst_id"))
//                .size() == 0
//                && answerRadioMapper.selectList(new QueryWrapper<AnswerRadio>()
//                        .eq("user_id", userId)
//                        .eq("form_id", formId)
//                        .eq("is_submit", false)
//                        .isNull(!type, "flow_inst_id")
//                        .isNotNull(type, "flow_inst_id"))
//                .size() == 0
//                && answerCheckboxMapper.selectList(new QueryWrapper<AnswerCheckbox>()
//                        .eq("user_id", userId)
//                        .eq("form_id", formId)
//                        .eq("is_submit", false)
//                        .isNull(!type, "flow_inst_id")
//                        .isNotNull(type, "flow_inst_id"))
//                .size() == 0
//                && answerListboxMapper.selectList(new QueryWrapper<AnswerListbox>()
//                        .eq("user_id", userId)
//                        .eq("form_id", formId)
//                        .eq("is_submit", false)
//                        .isNull(!type, "flow_inst_id")
//                        .isNotNull(type, "flow_inst_id"))
//                .size() == 0
//                && answerDatetimeMapper.selectList(new QueryWrapper<AnswerDatetime>()
//                        .eq("user_id", userId)
//                        .eq("form_id", formId)
//                        .eq("is_submit", false)
//                        .isNull(!type, "flow_inst_id")
//                        .isNotNull(type, "flow_inst_id"))
//                .size() == 0
//                && answerSlideMapper.selectList(new QueryWrapper<AnswerSlide>()
//                        .eq("user_id", userId)
//                        .eq("form_id", formId)
//                        .eq("is_submit", false)
//                        .isNull(!type, "flow_inst_id")
//                        .isNotNull(type, "flow_inst_id"))
//                .size() == 0
//                && answerScoreMapper.selectList(new QueryWrapper<AnswerScore>()
//                        .eq("user_id", userId)
//                        .eq("form_id", formId)
//                        .eq("is_submit", false)
//                        .isNull(!type, "flow_inst_id")
//                        .isNotNull(type, "flow_inst_id"))
//                .size() == 0;
    }

    /**
     * 传入一个Object类型的问题
     * 返回该问题对应的type
     *
     * @param o
     * @return
     */
    private Integer getQuestionType(Object o) {
        Integer type = null;
        if (o instanceof QuestionBlank)
            type = ((QuestionBlank) o).getQuestionType();
        else if (o instanceof RadionAnswerDto)
            type = ((RadionAnswerDto) o).getQuestionType();
        else if (o instanceof CheckboxOptionDto)
            type = ((CheckboxOptionDto) o).getQuestionType();
        else if (o instanceof ListboxAnswerDto)
            type = ((ListboxAnswerDto) o).getQuestionType();
        else if (o instanceof QuestionSlide)
            type = ((QuestionSlide) o).getQuestionType();
        else if (o instanceof QuestionDatetime)
            type = ((QuestionDatetime) o).getQuestionType();
        return type;
    }

    private Integer getQuestionOrderId(Object o) {

        Integer orderId = 0;
        if (o instanceof QuestionBlank)
            orderId = ((QuestionBlank) o).getOrderId();
        else if (o instanceof RadionAnswerDto)
            orderId = ((RadionAnswerDto) o).getOrderId();
        else if (o instanceof CheckboxOptionDto)
            orderId = ((CheckboxOptionDto) o).getOrderId();
        else if (o instanceof ListboxAnswerDto)
            orderId = ((ListboxAnswerDto) o).getOrderId();
        else if (o instanceof QuestionSlide)
            orderId = ((QuestionSlide) o).getOrderId();
        else if (o instanceof QuestionDatetime)
            orderId = ((QuestionDatetime) o).getOrderId();
        return orderId;

    }

    //获取表单中数据的一些函数

    /*************************************************************************************/

    //修改表单状态
    @Override
    public R editFormStatus(Map<String, Object> body) {
        //参数校验
        if (body.isEmpty() || !body.containsKey("formId") || !body.containsKey("formStatus"))
            return R.error("修改失败！");
        //获取参数
        String formId = body.get("formId").toString();
        Integer formStatus = Integer.valueOf(body.get("formStatus").toString());
        //数据库查询
        QueryWrapper<MyForm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", formId);
        //更新对应表单的状态
        if (myFormMapper.update(new MyForm().setFormStatus(formStatus), queryWrapper) == 1)
            return R.ok("修改状态成功！");
        else return R.error("修改失败！");
    }

    /**
     * 加如白名单
     * ToDo 匿名
     * 具体实现
     * 判断当前展示表单是否第一次填写  是-->直接返回
     * 否-->调用showFormStorage
     **/
    @Override
    public R showForm(HttpServletRequest request, Map<String, Object> body) {
        //表单是否存在
        if (!body.containsKey("formId"))
            return R.error("参数错误！");

        String formId = body.get("formId").toString();

        //校验表单权限
        MyForm myForm = myFormMapper.selectOne(new QueryWrapper<MyForm>().eq("id", formId));
        if (null == myForm) return R.error("表单不存在！");
        //查询表单类型 企业表单还是个人表单
        Boolean type = false;

        if (body.containsKey("type"))
            type = (Boolean) body.get("type");

        /**
         * getFormInfo
         *
         */
        if (body.containsKey("getFormInfo"))
            return getFormInfo(myForm);

        /**
         * 如果showForm包含recordId 返回对应recordId记录
         */
        if (body.containsKey("recordId")) {
            String recordId = body.get("recordId").toString();
            return this.showFormStorage(recordId, formId, type);

        }
        //typeCode 0 返回答案
        //         1 新的表单
        //         2 不能重复填写
        //         3 不能匿名填写
        /**
         * 表单的校验
         */
        String ip = (String) body.get("ip");

//        System.out.println(getAuthentication().getPrincipal().equals("anonymousUser"));
        //是否允许匿名填写  不允许匿名且token非法 返回提示登录
        if (!myForm.getIsAnonymous() && getAuthentication().getPrincipal().equals("anonymousUser"))
            return R.ok("请登录后填写！").put("typeCode", 3);




        //允许匿名填写 检测是否有token 有id为userId  否则为-1
        //用户id
        Long userId = getAuthentication().getPrincipal().equals("anonymousUser") ? -1 : getUserId();


        //ip限制
        if (myForm.getIpLimit()) {
            //获取前端ip
            WriteRecord writeRecord = writeRecordMapper.selectOne(
                    new QueryWrapper<WriteRecord>()
                            .eq("form_id", formId)
                            .eq("user_id", userId)
                            .eq("ip", ip)
                            .eq("is_submit", true)
            );
            if (writeRecord != null)
                return R.ok("ip限制只能填写一份").put("typeCode", 2);
        }


        //userId!=-1 非匿名 答案 && userId在答案表 isSubmit为false
        if (!checkIfSubmit(userId, formId, type)) {
            WriteRecord writeRecord = writeRecordMapper.selectOne(
                    new QueryWrapper<WriteRecord>()
                            .eq("form_id", formId)
                            .eq("user_id", userId)
                            .eq("is_submit", false)
            );
            return this.showFormStorage(writeRecord.getId(), formId, type);
        }

        //调用带答案查询的返回


        //userId==-1 || checkIfSubmit
        //返回的数据  不需要查答案
        WriteRecord writeRecord = new WriteRecord();

            writeRecord
                    .setId(UUID.randomUUID().toString())
                    .setFormId(formId)
                    .setFormName(myForm.getFormName())
                    .setUserId(userId)
                    .setUserId(userId)
                    .setFormTags(myForm.getTags())
                    .setIp(ip)
                    .setIsSubmit(false)
                    .setTime(new Date(System.currentTimeMillis()))
                    .setAllCanSee(myForm.getAllCanSee());
        writeRecordMapper.insert(writeRecord);


        Map<String, Object> form = new HashMap<>();
        form.put("formInfo", myForm);

        List<Object> questions = getQuestions(formId);
        form.put("questions", questions);
        form.put("userId", userId);
        form.put("type", "开始填写一份新的表单吧！");
        return R.ok("查询成功").put("form", form).put("typeCode", 1).put("recordId", writeRecord.getId());
    }

    /**
     * 返回表单 新表单
     * 供查询结果使用
     *
     * @return
     */
    private R getFormInfo(MyForm myForm) {
        Map<String, Object> form = new HashMap<>();
        form.put("formInfo", myForm);
        List<Object> questions = getQuestions(myForm.getId());
        form.put("questions", questions);
        form.put("userId", myForm.getUserId());
        return R.ok("获取表单信息成功").put("form", form);
    }

    /**
     * 暂存的答案和问题
     */
    private R showFormStorage(String recordId, String formId, Boolean type) {

        MyForm myForm = myFormMapper.selectOne(new QueryWrapper<MyForm>().eq("id", formId));
        if (myForm == null) return R.error("表单不存在");
        Map<String, Object> form = new HashMap<>();
        form.put("formInfo", myForm);
        //问题list questions
        List<Object> questions = getQuestions(formId);
        //答案 list answers
        List<Object> answers = getAnswersStore(recordId, questions, type);
        //遍历questions

        WriteRecord writeRecord = writeRecordMapper.selectOne(
                new QueryWrapper<WriteRecord>()
                        .eq("form_id", formId)
                        .eq("id", recordId)
                        .eq("is_submit", false)
        );

        Long userId = getAuthentication().getPrincipal().equals("anonymousUser") ? -1 : getUserId();


        form.put("questions", questions);
        form.put("answers", answers);
        form.put("userId", userId);
        form.put("type", "该表单还未填写完毕,请继续填写!");
        return R.ok("查询成功").put("form", form).put("typeCode", 0).put("recordId", writeRecord != null ? writeRecord.getId() : null);
    }


    //ToDo
    @Override
    public R submitForm(HttpServletRequest request, Map<String, Object> body) {
        if (null == body || !body.containsKey("formId") || !body.containsKey("recordId"))
            return R.error("参数传递有误");

        String formId = body.get("formId").toString();

        String recordId = body.get("recordId").toString();

        //校验表单权限
        MyForm myForm = myFormMapper.selectOne(new QueryWrapper<MyForm>().eq("id", formId));
        if (null == myForm) return R.error("表单不存在！");


        //允许匿名填写 检测是否有token 有id为userId  否则为-1
        //允许匿名填写
        //用户id
//        Integer userId = myForm.getIsAnonymous() ? -1 : TokenUtil.getId(request);
        Integer userId = getAuthentication().getPrincipal().equals("anonymousUser") ? -1 : Math.toIntExact(getUserId());

        //更新表单数量
        myFormMapper.updateById(myForm.setCounts(myForm.getCounts() + 1));//更新

        WriteRecord writeRecord = writeRecordMapper.selectOne(
                new QueryWrapper<WriteRecord>()
                        .eq("form_id", formId)
                        .eq("user_id", userId)
                        .eq("is_submit", false));
        writeRecord.setIsSubmit(true);

        writeRecordMapper.updateById(writeRecord);

        //修改答案表
//        type 0
        answerBlankMapper.selectList(
                new QueryWrapper<AnswerBlank>().eq("form_id", formId).eq("user_id", userId).eq("is_submit", false)
        ).forEach(i -> answerBlankMapper.updateById(i.setIsSubmit(true)));
        //type 1
        answerRadioMapper.selectList(
                new QueryWrapper<AnswerRadio>().eq("form_id", formId).eq("user_id", userId).eq("is_submit", false)
        ).forEach(i -> answerRadioMapper.updateById(i.setIsSubmit(true)));
        //type 2
        answerCheckboxMapper.selectList(
                new QueryWrapper<AnswerCheckbox>().eq("form_id", formId).eq("user_id", userId).eq("is_submit", false)
        ).forEach(i -> answerCheckboxMapper.updateById(i.setIsSubmit(true)));
        //type 3
        answerListboxMapper.selectList(
                new QueryWrapper<AnswerListbox>().eq("form_id", formId).eq("user_id", userId).eq("is_submit", false)
        ).forEach(i -> answerListboxMapper.updateById(i.setIsSubmit(true)));
        //type 4
        answerSlideMapper.selectList(
                new QueryWrapper<AnswerSlide>().eq("form_id", formId).eq("user_id", userId).eq("is_submit", false)
        ).forEach(i -> answerSlideMapper.updateById(i.setIsSubmit(true)));
        //type 5
        answerDatetimeMapper.selectList(
                new QueryWrapper<AnswerDatetime>().eq("form_id", formId).eq("user_id", userId).eq("is_submit", false)
        ).forEach(i -> answerDatetimeMapper.updateById(i.setIsSubmit(true)));
        //type 6
        answerScoreMapper.selectList(
                new QueryWrapper<AnswerScore>().eq("form_id", formId).eq("user_id", userId).eq("is_submit", false)
        ).forEach(i -> answerScoreMapper.updateById(i.setIsSubmit(true)));

        return R.ok("提交成功");
    }

    //ToDo
    @Override
    public R deleteFormById(Map<String, Object> body) {
        return null;
    }

    /**
     * 查询表单作答情况  ---一份一份的
     * pageNo    =?
     * pageSisze = 1
     * @param body
     * @return
     */
    @Override
    public R checkResult(Map<String, Object> body) {
        if (body == null || !body.containsKey("formId") || !body.containsKey("pageNo"))
            return R.error("参数错误");
        //表单id
        String formId = body.get("formId").toString();
        //
        Integer pageNo = (Integer) body.get("pageNo");
        //返回体
        Map<String, Object> resMap = new HashMap<>();
        //表单信息
        MyForm myForm = myFormMapper.selectById(formId);
        resMap.put("formInfo", myForm);
        //答卷数量
        Integer counts = myForm.getCounts();
        if (counts == 0) return R.error("暂无作答信息");
        if (pageNo > counts) return R.error("答卷数据去火星了！");
        //问题信息
        List<Object> questions = getQuestions(formId);
        resMap.put("questions", questions);
        //答案信息
        LinkedList<Object> answer = getAnswerListAt(questions, pageNo);
        resMap.put("answer", answer);
        //问卷数量
        resMap.put("counts", counts);

        return R.ok("查询问卷结果成功").put("result", resMap);
    }

    private LinkedList<Object> getAnswerListAt(List<Object> questions, Integer pageNo) {
        //返回结果
        LinkedList<Object> answer = new LinkedList<Object>();
        for (Object q : questions) {
            switch (getQuestionType(q)) {
                //填空
                case 0:
                    answer.add(answerBlankMapper
                            .selectList(
                                    new QueryWrapper<AnswerBlank>()
                                            .eq("is_submit", true)
                                            .eq("question_id", ((QuestionBlank) q).getId()))
                            .get(pageNo));
                    break;
                //单选
                case 1:
                    answer.add(answerRadioMapper
                            .selectList(
                                    new QueryWrapper<AnswerRadio>()
                                            .eq("is_submit", true)
                                            .eq("question_id", ((RadionAnswerDto) q).getId()
                                            )).get(pageNo));
                    break;
                //多选
                case 2: {

                    //按id分组

                    AnswerCheckbox checkbox = answerCheckboxMapper.selectList(
                            new QueryWrapper<AnswerCheckbox>()
                                    .select("DISTINCT(id),user_id,form_id,question_id,option_id,create_time,is_submit,flow_inst_id")
                                    .eq("is_submit", true)
                                    .eq("question_id", ((CheckboxOptionDto) q).getId())
                    ).get(pageNo);
                    List<AnswerCheckbox> answerCheckboxEntities = answerCheckboxMapper.selectList(
                            new QueryWrapper<AnswerCheckbox>()
                                    .eq("id", checkbox.getId())
                    );
                    ArrayList<String> optionId = new ArrayList<>();
                    answerCheckboxEntities.forEach(option -> optionId.add(option.getOptionId()));

                    answer.add(new CheckboxAnswerDto()
                            .setId(answerCheckboxEntities.get(0).getId())
                            .setUserId(answerCheckboxEntities.get(0).getUserId())
                            .setFormId(answerCheckboxEntities.get(0).getFormId())
                            .setQuestionId(answerCheckboxEntities.get(0).getQuestionId())
                            .setOptionId(optionId)
                            .setCreateTime(answerCheckboxEntities.get(0).getCreateTime())
                            .setIsSubmit(answerCheckboxEntities.get(0).getIsSubmit())
                    );
                }
                break;
                //下拉框
                case 3:
                    answer.add(answerListboxMapper.selectList(
                            new QueryWrapper<AnswerListbox>()
                                    .eq("is_submit", true)
                                    .eq("question_id", ((ListboxAnswerDto) q).getId())
                    ).get(pageNo));
                    //滑动条
                case 4:
                    answer.add(answerSlideMapper.selectList(
                            new QueryWrapper<AnswerSlide>()
                                    .eq("is_submit", true)
                                    .eq("question_id", ((QuestionSlide) q).getId())
                    ).get(pageNo));
                    break;
                //日期时间
                case 5: {
                    //日期时间
                    AnswerDatetime answerDatetime = answerDatetimeMapper.selectList(new QueryWrapper<AnswerDatetime>()
                            .eq("question_id", ((QuestionDatetime) q).getId())
                            .eq("is_submit", true)).get(pageNo);

                    Date[] dates = {answerDatetime.getBeginTime(), answerDatetime.getEndTime()};
                    //日期时间
                    answer.add(new DateTimeAnswerDto().setId(answerDatetime.getId())
                            .setUserId(answerDatetime.getUserId())
                            .setFormId(answerDatetime.getFormId())
                            .setQuestionId(answerDatetime.getQuestionId())
                            .setCreateTime(answerDatetime.getCreateTime())
                            .setBeginAndEnd(dates));
                }
                break;
                //评分
                case 6:
                    answer.add(answerScoreMapper.selectList(
                            new QueryWrapper<AnswerScore>()
                                    .eq("is_submit", true)
                                    .eq("question_id", ((QuestionScore) q).getId())
                    ).get(pageNo));
                    break;

                default:
                    break;
            }

        }
        return answer;
    }

    //创建表单
    @Override
    public R saveForm(MyForm myForm) {
        int insert = myFormMapper.insert(myForm);
        return insert == 1 ? R.ok("创建表单成功！") : R.error("创建失败！");
    }
    //null检测
//        if (null == body || !body.containsKey("formId") || !body.containsKey("formName"))
//            return R.error("创建表单失败！");
//        //创建者id
////        Integer userId = TokenUtil.getId(request);
//        Integer userId = Math.toIntExact(getUserId());
//        //表单id
//        String formId = body.get("formId").toString();
//        //表单名称
//        String formName = body.get("formName").toString();
//        //url  ToDo
//        String formUrl = "http://localhost:89/#/others/user_fill/?formId=" + formId;
//        //ipLimit
//        Boolean ipLimit = (body.containsKey("ipLimit")) ? (Boolean) body.get("ipLimit") : false;
//        Boolean isAnonymous = body.containsKey("isAnonymous") ? (Boolean) body.get("isAnonymous") : true;
//
//        //sql插入  设置各属性
//        int insert = myFormMapper.insert(
//                new MyForm()
//                        .setId(formId)
//                        .setUserId(userId)
//                        .setFormName(formName)
//                        .setCounts(0)
//                        .setFormStatus(0)
//                        .setFormUrl(formUrl)
//                        .setCreateTime(new Date(System.currentTimeMillis()))
//                        .setTimeLimit(false)
//                        .setIpLimit(ipLimit)
//                        .setIsAnonymous(isAnonymous)
//        );
//        if (insert == 1)
//            return R.ok("创建表单成功！");
//        else
//            return R.error("创建失败！");
//    }


    /**
     * 分页查询个人或企业表单信息
     *
     * @param formDto
     * @return
     */
    @Override
    public R queryFormList(MyFormDto formDto) {
        if (null == formDto)
            return R.error("请求体为空");
        System.out.println(formDto);
        //创建查询
        QueryWrapper<MyForm> queryWrapper = new QueryWrapper<>();

        if (formDto.getType())
            queryWrapper = querryDeprForm(formDto);
        else
            queryWrapper = queryUserForm(formDto);


        //查询
        Page<MyForm> formEntityPage = myFormMapper.selectPage(
                new Page<>(formDto.getPageNo(), formDto.getPageSize()), queryWrapper);
        //总数
        Long counts = myFormMapper.selectCount(queryWrapper);
        //个人表单
        if (!formDto.getType())
            return null == formEntityPage ? R.ok("暂无表单!") : R.ok("查询成功!").put("forms", formEntityPage.getRecords()).put("counts", counts);
        //企业表单
        //对表单进行封装
        List<QueryFormDto> res = new LinkedList<>();
        List<MyForm> records = formEntityPage.getRecords();
        for (MyForm f : records) {
            SysUser user = sysUserMapper.selectUserById(Long.valueOf(f.getUserId()));

            res.add(new QueryFormDto()
                    .setForm(f)
                    .setUserName(user.getUserName())
                    .setNickName(user.getNickName())
                    .setDeptName(user.getDept().getDeptName()));
        }
        return null == formEntityPage ? R.ok("暂无表单!") : R.ok("查询成功!").put("forms", res).put("counts", counts);
    }

    private QueryWrapper<MyForm> queryUserForm(MyFormDto formDto) {
        Long userId = getUserId();
        //创建查询
        QueryWrapper<MyForm> queryWrapper = new QueryWrapper<>();
        //筛选条件  状态筛选 表单名称筛选 表单创建日期时间范围
        queryWrapper
                //用户id
                .eq("user_id", userId)
                //默认查询未删除的表单
                .ge(StringUtils.isNull(formDto.getFormStatus()), "form_status", -1)
                //查询指定状态表单列表
                .eq(StringUtils.isNotNull(formDto.getFormStatus()), "form_status", formDto.getFormStatus())
                //表单名称模糊查询
                .like(StringUtils.isNotNull(formDto.getFormName()), "form_name", formDto.getFormName())
                //部门id
                .isNull("department_id")
                //标签
                .like(StringUtils.isNotNull(formDto.getTag()) && !formDto.getTag().equals(","), "tags", formDto.getTag())
                //查询日期范围内的表单
                .apply(null != formDto.getDateRange() && StringUtils.isNotNull(formDto.getDateRange().get("beginTime")),
                        "date_format (create_time,'%Y-%m-%d') >= date_format('" + formDto.getDateRange().get("beginTime") + "','%Y-%m-%d')")
                .apply(null != formDto.getDateRange() && StringUtils.isNotNull(formDto.getDateRange().get("endTime")),
                        "date_format (create_time,'%Y-%m-%d') <= date_format('" + formDto.getDateRange().get("endTime") + "','%Y-%m-%d')");
        return queryWrapper;
    }

    private QueryWrapper<MyForm> querryDeprForm(MyFormDto formDto) {
        //创建查询
        QueryWrapper<MyForm> queryWrapper = new QueryWrapper<>();
//        System.out.println(formDto.getUserName());

        //匹配用户名的用户id数组
        List<Long> userIds = new LinkedList<>();
        if (StringUtils.isNotNull(formDto.getUserName())) {
            userIds.addAll(sysUserMapper.selectIdsByUserName(formDto.getUserName()));
        }
        System.out.println(userIds);

        //查询条件    用户名筛选  表单名称
        queryWrapper
                .eq(StringUtils.isNotNull(formDto.getUserName()) && userIds.isEmpty(), "user_id", -1L)
                //用户名
                .in(!userIds.isEmpty(), "user_id", userIds)
                //表单状态
                .eq(StringUtils.isNotNull(formDto.getFormStatus()), "form_status", formDto.getFormStatus())
                //部门id
                .in(null != formDto.getDeptIds(), "department_id", formDto.getDeptIds())
                //表单名称
                .like(StringUtils.isNotNull(formDto.getFormName()), "form_name", formDto.getFormName())
                //标签
                .like(StringUtils.isNotNull(formDto.getTag()) && !formDto.getTag().equals(","), "tags", formDto.getTag())
                //创建时间
                .apply(null != formDto.getDateRange() && StringUtils.isNotNull(formDto.getDateRange().get("beginTime")),
                        "date_format (create_time,'%Y-%m-%d') >= date_format('" + formDto.getDateRange().get("beginTime") + "','%Y-%m-%d')")
                .apply(null != formDto.getDateRange() && StringUtils.isNotNull(formDto.getDateRange().get("endTime")),
                        "date_format (create_time,'%Y-%m-%d') <= date_format('" + formDto.getDateRange().get("endTime") + "','%Y-%m-%d')");
        return queryWrapper;

    }


    @Override
    //以List形式返回
    public List<MyForm> querywithId(String Id) {
        QueryWrapper<MyForm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", Id);
        return myFormMapper.selectList(queryWrapper);
    }

    @Override
    public Map<String, Object> summerizeForm(String FormId) {
        List<MyForm> FormMessage = new ArrayList<>();
        FormMessage = querywithId(FormId);
        Map<String, Object> FormSummrizeMessage = new HashMap<>();
        FormSummrizeMessage.put("FormMessage", FormMessage);
        //TODO:信息未填充完成
        return FormSummrizeMessage;
    }

    @Override
    //查询一个问题表单中所有的回答内容
    //输入：form_id
    //输出：表单中所有问题的答案
    public Map<String, Object> QueryFormResult(HttpServletRequest request, Map<String, Object> body) {
//        Integer userId = TokenUtil.getId(request);
        Integer userId = Math.toIntExact(getUserId());
        String formId = body.get("form_id").toString();
        Map<String, Object> TotalAnswer = new HashMap<String, Object>();
        //查表
        QueryWrapper<MyForm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", formId);
        List<MyForm> queryWrapperList = myFormMapper.selectList(queryWrapper);

        QueryWrapper<AnswerBlank> answerBlankEntityQueryWrapper = new QueryWrapper<>();
        answerBlankEntityQueryWrapper.eq("form_id", formId);
        List<AnswerBlank> answerBlankList = answerBlankMapper.selectList(answerBlankEntityQueryWrapper);

        QueryWrapper<AnswerCheckbox> answerCheckboxQueryWrapper = new QueryWrapper<>();
        answerCheckboxQueryWrapper.eq("form_id", formId);
        List<AnswerCheckbox> answerCheckboxList = answerCheckboxMapper.selectList(answerCheckboxQueryWrapper);

        QueryWrapper<AnswerDatetime> answerDatetimeEntityQueryWrapper = new QueryWrapper<>();
        answerDatetimeEntityQueryWrapper.eq("form_id", formId);
        List<AnswerDatetime> answerDatetimeList = answerDatetimeMapper.selectList(answerDatetimeEntityQueryWrapper);

        QueryWrapper<AnswerListbox> answerListboxEntityQueryWrapper = new QueryWrapper<>();
        answerListboxEntityQueryWrapper.eq("form_id", formId);
        List<AnswerListbox> answerListboxList = answerListboxMapper.selectList(answerListboxEntityQueryWrapper);

        QueryWrapper<AnswerRadio> answerRadioEntityQueryWrapper = new QueryWrapper<>();
        answerRadioEntityQueryWrapper.eq("form_id", formId);
        List<AnswerRadio> answerRadioList = answerRadioMapper.selectList(answerRadioEntityQueryWrapper);

        QueryWrapper<AnswerSlide> answerSlideEntityQueryWrapper = new QueryWrapper<>();
        answerSlideEntityQueryWrapper.eq("form_id", formId);
        List<AnswerSlide> answerSlideList = answerSlideMapper.selectList(answerSlideEntityQueryWrapper);

//        加入forminfo


        if (queryWrapperList != null)
            TotalAnswer.put("formInfo", queryWrapperList);
        if (answerRadioList != null)
            TotalAnswer.put("AnswerRadioEntityList", answerRadioList);
        if (answerCheckboxList != null)
            TotalAnswer.put("AnswerCheckboxEntityList", answerCheckboxList);
        if (answerBlankList != null)
            TotalAnswer.put("AnswerBlankEntityList", answerBlankList);
        if (answerDatetimeList != null)
            TotalAnswer.put("AnswerDatetimeEntityList", answerDatetimeList);
        if (answerListboxList != null)
            TotalAnswer.put("AnswerListboxEntityList", answerListboxList);
        if (answerSlideList != null)
            TotalAnswer.put("AnswerSlideEntityList", answerSlideList);
        return TotalAnswer;

//        if (null == TotalAnswer)
//            return R.ok(2000, "暂无信息!");
//        else
//            return R.ok(20000, "查询成功!").put("form", TotalAnswer);
    }
    @Override
    public R saveWork(HttpServletRequest request, Map<String, Object> body) {
        if (null == body || !body.containsKey("formId") || !body.containsKey("formName"))
            return R.error(2000, "保存业务表失败");
        //创建者id
        Integer userId = TokenUtil.getId(request);
        //url  ToDo
        String formUrl = "http://localhost:89/#/others/user_fill/?formId=" + body.get("formId").toString();
        //sql插入  设置各属性
        int insert = myFormMapper.insert(
                new MyForm()
                        .setId(body.get("id").toString())
                        .setUserId(userId)
                        .setFormName(body.get("formName").toString())
                        .setCounts(Integer.parseInt(body.get("counts").toString()))
                        .setFormInfo(body.get("formInfo").toString())
                        .setFormStatus(Integer.parseInt(body.get("formStatus").toString()))
                        .setFormUrl(formUrl)
                        .setCreateTime(new Date(System.currentTimeMillis()))
                        .setTimeLimit(false)
                        .setBeginTime(null)
                        .setEndTime(null)
                        .setFormPassword(null)
                        .setIpLimit(false)
                        .setIsAnonymous(true)
                        .setDepartmentId(null)
        );
        if (insert == 1)
            return R.ok(20000, "保存成功！");
        else
            return R.error(2000, "保存失败！");

    }

    @Override
    public List<MyForm> queryWithdepartmentId(Map<String, Object> body) {
        QueryWrapper<MyForm> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("department_id", body.get("id"));
        return myFormMapper.selectList(queryWrapper);
    }
}
